using System;
using System.Collections.Generic;
using System.Text;
using Csla;
using System.Data;
using Active.Core.DB;
using Csla.Data;
using DesignByContract;

namespace Active.Core
{
    /// <summary>
    /// The read only media info list.
    /// </summary>
    [Serializable()]
    public class MediaList :
      ReadOnlyListBase<MediaList, MediaInfo>
    {
        #region Paging

        private int _totalRecordsCount;
        /// <summary>
        /// Gets the total records count.
        /// </summary>
        /// <value>The total records count.</value>
        public int TotalRecordsCount
        {
            get
            {
                return _totalRecordsCount;
            }
        }

        private int _pageNo;
        /// <summary>
        /// Gets the page no.
        /// </summary>
        /// <value>The page no.</value>
        public int PageNo
        {
            get
            {
                return _pageNo;
            }
        }

        private int _pageSize;
        /// <summary>
        /// Gets the size of the page.
        /// </summary>
        /// <value>The size of the page.</value>
        public int PageSize
        {
            get
            {
                return _pageSize;
            }
        }

        private bool _allowPaging = false;
        /// <summary>
        /// Gets a value indicating whether [allow paging].
        /// </summary>
        /// <value><c>true</c> if [allow paging]; otherwise, <c>false</c>.</value>
        public bool AllowPaging
        {
            get
            {
                return _allowPaging;
            }
        }

        #endregion

        #region Authorization Rules

        public static bool CanGetObject()
        {
            // TODO: customize to check user role
            //return ApplicationContext.User.IsInRole("");
            return true;
        }

        #endregion

        #region Factory Methods

        /// <summary>
        /// Gets the media list.
        /// </summary>
        /// <returns></returns>
        public static MediaList GetMediaList()
        {
            return GetMediaList(0);
        }

        public static MediaList GetMediaList(int regionId)
        {
            return DataPortal.Fetch<MediaList>(new Criteria(regionId));
        }

        /// <summary>
        /// Gets the media list.
        /// </summary>
        /// <param name="pageNo">The page no.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <returns></returns>
        public static MediaList GetMediaList(int pageNo, int pageSize)
        {
            Check.Require(pageNo > 0);
            Check.Require(pageSize > 0);
            return GetMediaList(0, pageNo, pageSize);
        }

        /// <summary>
        /// Gets the media list.
        /// </summary>
        /// <param name="regionId">The region id.</param>
        /// <param name="pageNo">The page no.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <returns></returns>
        public static MediaList GetMediaList(int regionId, int pageNo, int pageSize)
        {
            Check.Require(pageNo > 0);
            Check.Require(pageSize > 0);
            return DataPortal.Fetch<MediaList>(new Criteria(regionId, pageNo, pageSize));
        }

        /// <summary>
        /// Gets the media list.
        /// </summary>
        /// <param name="regionId">The region id.</param>
        /// <param name="nameToSeartch">The name to seartch.</param>
        /// <param name="pageNo">The page no.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <returns></returns>
        public static MediaList GetMediaList(int regionId, string nameToSeartch, int pageNo, int pageSize)
        {
            Check.Require(pageNo > 0);
            Check.Require(pageSize > 0);
            return DataPortal.Fetch<MediaList>(new Criteria(regionId, nameToSeartch, pageNo, pageSize));
        }

        private MediaList()
        { /* require use of factory methods */ }

        #endregion

        #region Data Access

        [Serializable()]
        private class Criteria
        {
            private string _nameToSearch;
            public string NameToSearch
            {
                get { return _nameToSearch; }
            }

            private int _pageNo;
            public int PageNo
            {
                get
                {
                    return _pageNo;
                }
            }

            private int _pageSize;
            public int PageSize
            {
                get
                {
                    return _pageSize;
                }
            }

            private bool _allowPaging = false;
            public bool AllowPaging
            {
                get
                {
                    return _allowPaging;
                }
            }

            private int _regionId = 0;
            public int RegionId
            {
                get
                {
                    return _regionId;
                }
            }

            public Criteria(int regionId)
            {
                _regionId = regionId;
            }

            public Criteria(int regionId, int pageNo, int pageSize)
            {
                _regionId = regionId;
                _pageNo = pageNo;
                _pageSize = pageSize;
                _allowPaging = true;
            }

            public Criteria(int regionId, string nameToSearch, int pageNo, int pageSize)
            {
                _regionId = regionId;
                _nameToSearch = nameToSearch;
                _pageNo = pageNo;
                _pageSize = pageSize;
                _allowPaging = true;
            }
        }

        private void DataPortal_Fetch(Criteria criteria)
        {
            RaiseListChangedEvents = false;
            IsReadOnly = false;

            NBearLite.SelectSqlSection select =
                DataService.DBService.Select(Tables.Medias,
                Tables.Medias.Id, Tables.Medias.Name, Tables.Medias.Advance,
                Tables.Medias.Brokerage, Tables.Medias.Category, Tables.Medias.DealTimes);
            NBearLite.WhereClip where = NBearLite.WhereClip.All;
            if (!string.IsNullOrEmpty(criteria.NameToSearch))
            {
                where.And(Tables.Medias.Name.Contains(criteria.NameToSearch));
            }
            if (criteria.AllowPaging)
            {
                select.SetSelectRange(criteria.PageSize,
                    (criteria.PageNo - 1) * criteria.PageSize,
                    Tables.Medias.Id);
                _allowPaging = true;
                _pageNo = criteria.PageNo;
                _pageSize = criteria.PageSize;
            }
            select.OrderBy(Tables.Medias.DealTimes.Desc);
            if (criteria.RegionId > 0)
            {
                where.And(Tables.Medias.RegionId == criteria.RegionId);
            }
            select.Where(where);
            using (SafeDataReader dr = new SafeDataReader(select.ToDataReader()))
            {
                while (dr.Read())
                    Add(MediaInfo.GetMediaInfo(dr));
            }
            if (_allowPaging)
            {
                select = DataService.DBService.Select(Tables.Medias,
                    Tables.Medias.Id.Count());
                select.Where(where);
                _totalRecordsCount = (int)select.ToScalar();
            }
            else
            {
                _totalRecordsCount = this.Count;
            }
            IsReadOnly = true;
            RaiseListChangedEvents = true;
        }

        #endregion
    }
}

